/*================================================================
*   Copyright (C) 2022 Sangfor Ltd. All rights reserved.
*   
*   文件名称：oj_server.cpp
*   创 建 者：wudu
*   创建日期：2022年04月24日
*   描    述：
*
================================================================*/


#include <stdio.h>
#include <iostream>

#include <jsoncpp/json/json.h>

#include "httplib.h"
#include "oj_model.hpp"
#include "oj_view.hpp"
#include "oj_compile.hpp"
using namespace httplib;
using namespace std;


int main(){
    /*
     * 1.httplib server类对象
     * 2.定义当前服务端可以处理的http请求
     * 3.指定http服务器的逻辑根目录
     * 4.http监听起来
     * */
    Server svr;
    OjModel om;

    svr.Get("/all_questions", [&om](const Request& requ, Response& resp){
            //1.获取全部试题信息
            vector<Question> vec;
            om.GetAllQuestions(vec);

            //2.渲染html页面， 获取html页面字节流， 为组织http响应做准备
            string html;
            OjView::DrawAllQuestionHtml(vec, &html); 

            resp.set_content(html, "text/html");
        });

    /*
     * 正则表达式
     *  \d : 表示1位数字
     *  \d+ ： 表示多位数字
     * */
    svr.Get(R"(/question/(\d+))", [&om](const Request& requ, Response& resp){
            //1.通过url当中的题目id， 区分当前需要获取哪一个试题
            //cout << requ.matches[1].str() << endl;
            //2.通过id， 在试题模块当中获取单个试题信息
            Question ques;
            om.GetOneQuestion(requ.matches[1].str(), &ques); 
            //3.渲染html页面
            string html;
            OjView::DrawoneQuestionHtml(ques, &html); 
            //4.构造响应， 返回给浏览器
            resp.set_content(html, "text/html");
        });

    svr.Post(R"(/compile/(\d+))", [&om](const Request& requ, Response& resp){
            //1.将收到的正文内容进行切分， 并且进行url的解码
            //   code=xxx&stdin=xxx
            unordered_map<string, string> body_kv;
            UrlUtil::PraseBody(requ.body, &body_kv);

            //2.通过试题模块查找当前试题的试题尾部代码（测试用例， main函数）
            Question ques;
            om.GetOneQuestion(requ.matches[1].str(), &ques);
            
            //3.组合用户提交的代码和自定义的尾部代码, 可以通过Json串来传递
            Json::Value req_json; 
            req_json["code"] = body_kv["code"] + ques.tail_;
            req_json["stdin"] = body_kv["stdin"];
            
            //4.代码交给编译运行模块进行编译运行
            Json::Value resp_json;
            Compiler::compile_and_run(req_json, resp_json);
            
            //5.回复响应
            string html;
            OjView::DrawCaseReaultHtml(resp_json, &html);

            resp.set_content(html, "text/html");
        });


    svr.set_base_dir("./www");
    svr.listen("0.0.0.0", 18989);
    return 0;
}
